/**
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
** \file IntervalObject.cpp
** \version $Id: IntervalObject.cpp 21 2009-10-20 19:37:56Z tyree731 $
*/

#include "IntervalObject.h"

IntervalObject::IntervalObject()
: Object("IntervalObject"),
  _privateStart(0),
  _privateEnd(0)
{
}

IntervalObject::IntervalObject(const int _begin, const int _end)
: Object("IntervalObject"),
  _privateStart(_begin),
  _privateEnd(_end)
{
}

IntervalObject::IntervalObject(const IntervalObject& other)
: Object("IntervalObject"),
  _privateStart(other._privateStart),
  _privateEnd(other._privateEnd)
{
}

IntervalObject::~IntervalObject()
{
}

unsigned int
IntervalObject::hash() const
{
  /* FNV offset basis */
  unsigned int result = 0x811c9dc5;
  for (int i = 24; i >= 0; i-=8) {
    /* XOR each octet of the ints with the result then multiply by FNV prime */
    result = ((_privateStart >> i) ^ result) * 16777619; 
    result = ((_privateEnd >> i) ^ result) * 16777619;
  }
  return result;
}

bool
IntervalObject::operator==(const Object& rhs) const
{
  const IntervalObject* _rhs = dynamic_cast<const IntervalObject*>(&rhs);
  return _rhs && (*this) == (*_rhs);
}

bool
IntervalObject::operator!=(const Object& rhs) const
{
  const IntervalObject* _rhs = dynamic_cast<const IntervalObject*>(&rhs);
  return _rhs && (*this) != (*_rhs);
}

bool
IntervalObject::operator<(const Object& rhs) const
{
  const IntervalObject* _rhs = dynamic_cast<const IntervalObject*>(&rhs);
  return _rhs && (*this) < (*_rhs);
}

bool
IntervalObject::operator>(const Object& rhs) const
{
  const IntervalObject* _rhs = dynamic_cast<const IntervalObject*>(&rhs);
  return _rhs && (*this) > (*_rhs);
}

bool
IntervalObject::operator<=(const Object& rhs) const
{
  const IntervalObject* _rhs = dynamic_cast<const IntervalObject*>(&rhs);
  return _rhs && (*this) <= (*_rhs);
}

bool
IntervalObject::operator>=(const Object& rhs) const
{
  const IntervalObject* _rhs = dynamic_cast<const IntervalObject*>(&rhs);
  return _rhs && (*this) >= (*_rhs);
}

bool
IntervalObject::operator==(const IntervalObject& rhs) const
{
  return (_privateStart == rhs._privateStart) &&
         (_privateEnd == rhs._privateEnd);
}

bool
IntervalObject::operator!=(const IntervalObject& rhs) const
{
  return (_privateStart != rhs._privateStart) ||
         (_privateEnd != rhs._privateEnd);
}

bool
IntervalObject::operator<(const IntervalObject& rhs) const
{
  if (_privateStart == rhs._privateStart)
    return _privateEnd < rhs._privateEnd;
  return _privateStart < rhs._privateStart;
}

bool 
IntervalObject::operator>(const IntervalObject& rhs) const
{
  if (_privateStart == rhs._privateStart)
    return _privateEnd > rhs._privateEnd;
  return _privateStart > rhs._privateStart;
}

bool
IntervalObject::operator<=(const IntervalObject& rhs) const
{
  if (_privateStart == rhs._privateStart)
    return _privateEnd <= rhs._privateEnd;
  return _privateStart <= rhs._privateStart;
}

bool
IntervalObject::operator>=(const IntervalObject& rhs) const
{
  if (_privateStart == rhs._privateStart)
    return _privateEnd >= rhs._privateEnd;
  return _privateStart >= rhs._privateStart;
}
